package keul.planner.tools;

import java.awt.Color;
import java.io.Serializable;

/**
 * Eine im Java-Modul entstandene Klasse, die Color beerbt,
 * soll Hilfestellungen bei der Farbwahl bieten.
 * @author kev
 */
public class Farbe extends Color implements Serializable {
	private static final long serialVersionUID = 1L;
	
	
	// Farbdefinition -------------------------------------------------------------------	
	@SuppressWarnings("hiding")
	public static final Farbe   schwarz     = new Farbe(   0,   0,   0 ),
                                    weiss       = new Farbe( 255, 255, 255 ),
	                            rot         = new Farbe( 255,   0,   0 ),
	                            tuerkis     = new Farbe(   0, 255, 255 ),    
	                            lila     	= new Farbe( 255,   0, 255 ),
	                            gruen       = new Farbe(   0, 255,   0 ),  
	                            blau        = new Farbe(   0,   0, 255 ),                                
	                            gelb        = new Farbe( 255, 255,   0 ),
	                            orange     	= new Farbe( 255,  63,   0 ),
	                            braun     	= new Farbe( 127,  63,   0 ),
	                            hellrot     = new Farbe( 255, 127, 127 ),
	                            dunkelgrau	= new Farbe(  63,  63,  63 ),
	                            grau        = new Farbe( 127, 127, 127 ),
	                            hellgruen	= new Farbe( 127, 255, 127 ),  
	                            hellblau 	= new Farbe( 127, 127, 255 ),                                
	                            hellgrau 	= new Farbe( 191, 191, 191 ),

                                bleu = new Farbe(  92, 198, 253 );

	public static final Farbe[] c64Farben = new Farbe[] {
		Farbe.schwarz,				//		C64-schwarz,	
		Farbe.weiss,				//		C64-weiss,	
		new Farbe( 104,  55,  43 ),		//		C64-rot,		
		new Farbe( 122, 191, 199 ),		//		C64-tuerkis,		
		new Farbe( 111,  61, 134 ),		//		C64-lila,		
		new Farbe(  88, 141,  67 ),		//		C64-gruen,	
		new Farbe(  53,  40, 121 ),		//		C64-blau,		
		new Farbe( 184, 199, 111 ),		//		C64-gelb,			
		new Farbe( 111,  79,  37 ),		//		C64-orange,	
		new Farbe(  67,  57,   0 ),		//		C64-braun,	
		new Farbe( 154, 103,  89 ),		//		C64-hellrot,	
		new Farbe(  68,  68,  68 ),		//		C64-dunkelgrau,	
		new Farbe( 108, 108, 108 ),		//		C64-grau,		
		new Farbe( 154, 210, 132 ),		//		C64-hellgruen,
		new Farbe( 108,  94, 181 ),		//		C64-hellblau,	
		new Farbe( 149, 149, 149 )		//		C64-hellgrau,		
	};
	
    // Felder --------------------------------------------------------------------------------------
    protected  int rgb = 0;
    // getter fuer eigene Felder -------------------------------------------------------------------
    public     int getRgb() 			{ return rgb; 					}
    // setter fuer eigene Felder -------------------------------------------------------------------
    public    void setRgb(int col)				{ this.rgb = col; 				}
    public    void setRgb(String hexcode) 		{ setRgb( hexStringToInt(hexcode) ); }
    public static int hexStringToInt(String hexcode) {
    	if (hexcode.substring(0, 1).equals("#"))
            hexcode = hexcode.substring(1);
        try { return Integer.parseInt(hexcode, 16); }
        catch (Exception e) { return 0; }
    }
    public    void setRgb(int r, int g, int b) 	{ setR(r); setG(g); setB(b); 	}
    // spezielle getter ---------------------------------------------------------------------------
    public     int getR() 				{ return (rgb >> 16) & 255; 	}
    public     int getG() 				{ return (rgb >> 8) & 255;  	}
    public     int getB() 				{ return (rgb) & 255;		  	}
    // spezielle setter ---------------------------------------------------------------------------
    public    void setR(int r) 			{
        if (r < 0) {
            r = 0;
        } else if (r > 255) {
            r = 255;
        }
        rgb = (r << 16) + (getG() << 8) + (getB());
    }
    public    void setG(int g) 			{
        if (g < 0) {
            g = 0;
        } else if (g > 255) {
            g = 255;
        }
        rgb = (getR() << 16) + (g << 8) + (getB());
    }
    public    void setB(int b) 			{
        if (b < 0) {
            b = 0;
        } else if (b > 255) {
            b = 255;
        }
        rgb = (getR() << 16) + (getG() << 8) + (b);
    }
    // --------------------------------------------------------------------------------------------

    // Konvertierungsmethoden ---------------------------------------------------------------------
    public     int toInt() 				{ return rgb; 					}
    public   Color toColor() 			{ return new Color(rgb); 		}
    @Override
    public  String toString() 			{ return toHexString(); 		}
    @Deprecated
    public  String toStringOld() 		{
        return String.format("%d <- %d, %d, %d <- %d, %d, %d", toInt(), getR() << 16, getG() << 8, getB(), getR(), getG(), getB());
    }
    public  String toBinaryString() 	{
        StringBuffer sb = new StringBuffer(Integer.toBinaryString(rgb));
        while ( sb.length() < 25 ) {
            sb.insert( 0, "0" );    //         _???????????????????1001 -> 000000000000000000001001
        }                           // ????????000000000000000000001001 -> 000000000000000000001001
        sb.insert( 9, " " );
        sb.insert( 18, " " );
        return sb.substring( sb.length() - 26, sb.length() );
    }
    public  String toHexString() 		{ return String.format("#%02X%02X%02X", getR(), getG(), getB()); }
    // ---
    public   Farbe mischen(Farbe f2) 	{ return mischen(this, f2); 								}
    public Boolean isHell() 			{ return ( (getR()+getG()+getB()) > (3*127) ); 				}
    public   Farbe aufhellen() 			{ return new Farbe(getR() + 16, getG() + 16, getB() + 16); 	}
    public   Farbe abdunkeln() 			{ return new Farbe(getR() - 16, getG() - 16, getB() - 16); 	}
    public   Farbe negativ() 			{ return new Farbe(255-getR(), 255-getG() , 255-getB() ); 	}
    public   Farbe transform(String s) 	{
    	Farbe farbe;
    	if ( s.equals("RBG") ) {
                farbe = new Farbe( getR(), getB(), getG() );
        } else if ( s.equals("GBR") ) {
                farbe = new Farbe( getG(), getB(), getR() );
        } else if ( s.equals("BRG") ) {
                farbe = new Farbe( getB(), getR(), getG() );
        } else if ( s.equals("GRB") ) {
                farbe = new Farbe( getG(), getR(), getB() );
        } else {
                farbe = new Farbe( getB(), getG(), getR() );
        } 
    	return farbe;
    	
    }
    // -------------------------------------------------------------------------------------------

    // statische Methoden -------------------------------------------------------------------------
    public  static Farbe mischen(Farbe f1, Farbe f2) {
        return new Farbe(
                (f1.getR() + f2.getR()) / 2,
                (f1.getG() + f2.getG()) / 2,
                (f1.getB() + f2.getB()) / 2);
    }
    // --------------------------------------------------------------------------------------------
    // override von Standardmethoden --------------------------------------------------------------

    @Override
    public boolean equals(Object o) 	{
        if (o instanceof Farbe) {
            return (rgb == ((Farbe) o).getRgb());
        }
        return false;
    }
    @Override
    public     int hashCode() 			{
        int hash = 3;
        hash = 79 * hash + this.rgb;
        return hash;
    }
    // --------------------------------------------------------------------------------------------

    // Konstruktoren ------------------------------------------------------------------------------
    public Farbe() 						{ super(0,0,0); }
    public Farbe(int r, int g, int b) 	{ super(r, g, b); setRgb(r, g, b); }
    public Farbe(int col) 				{ super(col); setRgb(col); }
    public Farbe(String hexcode) 		{ super(hexStringToInt(hexcode)); setRgb(hexcode); }
    // --------------------------------------------------------------------------------------------
}
